#ifndef GEX4_H
#define GEX4_H

typedef struct GEXHdr GEXHdr;
typedef struct GEXShdr GEXShdr;
void* theProgram;

// GEX4 Header

struct GEXHdr
{
	char magic[7]; //GEX4 SC
	char major; // Version major
	char minor; // Vesion minor
	char version; // Version of viper
	unsigned int entry; // Entry point
	unsigned int sectionCount; // How many sections
	unsigned int sectionTable; // pointer to section table
	unsigned int orgin; // Were to load....
	unsigned char subsystem; // Specific information relating to the GEXfile
};

// GEX4 Section Header

struct GEXShdr
{
	char name[8]; // Section name
	unsigned int length; // Section length
	unsigned int ptr; // points to the contents
};

char* getSymName(void* GEX, unsigned int address)
{
	GEXHdr* hdr = (GEXHdr*)GEX;
	int textSize = 0;
	if(strncmp("GEX4 SC",hdr->magic,7) == 0)
	{
		for(int i = 0; i < hdr->sectionCount;i++)
		{
			GEXShdr* section = (GEXShdr*)(GEX + (hdr->sectionTable + (i * sizeof(GEXShdr))));
			
			if(strncmp(section->name,".symtab",5) == 0)
			{
				int syms = 0;
				int tpos = 0;
				while(tpos < section->length)
				{
					char* nom = (char*)(GEX + section->ptr + tpos);
					for(pos;(char*)((char*)GEX + section->ptr + tpos)[0] != 0;tpos++);
					tpos += 1;
					unsigned int val = ((unsigned int*)(GEX + section->ptr + tpos))[0];
					tpos += 4;
					syms++;
					if(address == val)
						return nom;
					
				}
			}
		}
			return (void*)0;
	}
	else
	{
		return 0; 
	}
}
char* getSymAddress(void* GEX, unsigned int address)
{
	GEXHdr* hdr = (GEXHdr*)GEX;
	if(strncmp("GEX4 SC",hdr->magic,7) == 0)
	{
		for(int i = 0; i < hdr->sectionCount;i++)
		{
			GEXShdr* section = (GEXShdr*)(GEX + (hdr->sectionTable + (i * sizeof(GEXShdr))));
			
			if(strncmp(section->name,".symtab",5) == 0)
			{
				int syms = 0;
				int pos = 0;
				while(true)
				{
					char* nom = (char*)(GEX + section->ptr + pos);
					pos += 1 + strlen(nom);
					unsigned int val = ((unsigned int*)(GEX + section->ptr + pos))[0];
					pos += 4;
					if(syms == address)
						return val;
					syms++;
					
				}
			}
		}
			return (void*)0;
	}
	else
	{
		return 0; 
	}
}
void resolveExternalSymbols(void* program,void* program2)
{
	
}

void* openGEX(char* name)
{
	FILE* file = fopen(name,"r");
	fseek(file, 0L, SEEK_END); 
	int fileSize = ftell(file);
	char* GEX = (char*)malloc(fileSize);
	fseek(file, 0L, SEEK_SET);
	fread(GEX,1,fileSize,file);
	fclose(file);
	return GEX;
}

#include "gex/relocate.c"

#endif
